/*
 * Copyright (c) 2024 Hunan OpenValley Digital Industry Development Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

 #include "common_event_data.h"
 #include "common_event_manager.h"
 #include "common_event_subscriber.h"
 #include "common_event_support.h"
 #include "file_share_common.h"
 #include "file_share_errors.h"
 #include "file_share_log.h"
 #include "share_manager.h"
 #include "device_manager.h"
 #include "dm_constants.h"
 #include "dm_device_info.h"
 #include <securec.h>
 #include "share_manager.h"
 #include "string_ex.h"
 #include "device_manager.h"
 #include "dm_constants.h"
 #include "dm_device_info.h"
 #include "napi_file_share.h"
 #include "napi_file_share_util.h"
 
 using namespace OHOS::DistributedHardware;
 
 namespace OHOS {
 namespace FileShare {
 
 static std::mutex g_CommonEventMonitorMutex;
 
 class CommonEventMonitor : public EventFwk::CommonEventSubscriber {
 public:
     explicit CommonEventMonitor(const EventFwk::CommonEventSubscribeInfo &subscriberInfo);
     virtual ~CommonEventMonitor() {}
     void OnReceiveEvent(const EventFwk::CommonEventData &data) override;
 };
 
 class SubscribeEvent {
     public:
         static SubscribeEvent* instance; 
         static SubscribeEvent* getInstance() {
             if (instance == nullptr) {
                 instance = new SubscribeEvent();
             }
             return instance;
         }
         int32_t SubscribeCommonEvent();
         std::string m_pkgName;
         DmPublishInfo m_publishInfo;
         std::shared_ptr<FSNapiPublishCallback> m_callback;
         bool m_shareStatus = false;
     private:
         std::shared_ptr<CommonEventMonitor> subscriber_ = nullptr;
 
 };
 SubscribeEvent* SubscribeEvent::instance = nullptr;
 static bool SubscribeEventInited = false;
 static SubscribeEvent *g_subscriberPtr;
 
 CommonEventMonitor::CommonEventMonitor(const EventFwk::CommonEventSubscribeInfo &subscriberInfo)
     :CommonEventSubscriber(subscriberInfo)
 {
 }
 
 void CommonEventMonitor::OnReceiveEvent(const EventFwk::CommonEventData &data)
 {
     std::lock_guard<std::mutex> lock(g_CommonEventMonitorMutex);
     std::string action = data.GetWant().GetAction();
     LOGI("fileshare notify common event=%{public}s", action.c_str());
 
     bool shareStatus = true;
     ShareManager::GetInstance().GetShareStatus(shareStatus);
     if (shareStatus == false) {
         LOGE("shareStatus not enable yet.");
         return ;
     }
     if (action == EventFwk::CommonEventSupport::COMMON_EVENT_SCREEN_OFF || action == EventFwk::CommonEventSupport::COMMON_EVENT_SCREEN_LOCKED) {
         LOGI("DisableShare in");
         if(g_subscriberPtr->m_shareStatus == false) {
             LOGI("fileshare already disable share");
             return ;
         }
 
         int32_t ret = ShareManager::GetInstance().ChangeUuid(ORIGIN_UUID);
         if (ret != FS_SUCCESS) {
             LOGE("ChangeUuid failed, ret %{public}d", ret);
             return ;
         }
         ret = DeviceManager::GetInstance().UnPublishDeviceDiscovery(g_subscriberPtr->m_pkgName, g_subscriberPtr->m_publishInfo.publishId);
         if (ret != DM_OK) {
             LOGE("DisableShare failed, ret %{public}d", ret);
             ShareManager::GetInstance().ChangeUuid(FILE_SHARE_UUID);
             return ;
         }
         g_subscriberPtr->m_shareStatus = false;
     } else if(action == EventFwk::CommonEventSupport::COMMON_EVENT_SCREEN_ON || action == EventFwk::CommonEventSupport::COMMON_EVENT_SCREEN_UNLOCKED) {
         LOGI("EnableShare in");
         if(g_subscriberPtr->m_shareStatus == true) {
             LOGI("fileshare already enable share");
             return ;
         }
         int32_t ret = ShareManager::GetInstance().ChangeUuid(FILE_SHARE_UUID);
         if (ret != FS_SUCCESS) {
             LOGE("ChangeUuid failed, ret %{public}d", ret);
             return ;
         }
         ret = DeviceManager::GetInstance().PublishDeviceDiscovery(g_subscriberPtr->m_pkgName, g_subscriberPtr->m_publishInfo, g_subscriberPtr->m_callback);
         if (ret != DM_OK) {
             LOGE("EnableShare for bundleName %{public}s failed, ret %{public}d", g_subscriberPtr->m_pkgName.c_str(), ret);
             ShareManager::GetInstance().ChangeUuid(ORIGIN_UUID);
             ShareManager::GetInstance().SetShareStatus(false);
             return ;
         }
         g_subscriberPtr->m_shareStatus = true;
     } else{
         LOGE("not allow event %{public}s", action.c_str());
     }
 }
 
 int32_t SubscribeEvent::SubscribeCommonEvent()
 {
     if (SubscribeEventInited) {
         LOGI("fileshare already subscribed common event");
         return FS_SUCCESS;
     }
 
     EventFwk::MatchingSkills matchingSkills;
     matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_SCREEN_OFF);
     matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_SCREEN_ON);
     matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_SCREEN_LOCKED);
     matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_SCREEN_UNLOCKED);
     EventFwk::CommonEventSubscribeInfo subscriberInfo(matchingSkills);
     subscriber_ = std::make_shared<CommonEventMonitor>(subscriberInfo);
     if (!EventFwk::CommonEventManager::SubscribeCommonEvent(subscriber_)) {
         LOGE("fileshare subscribe common event err");
         return FS_FAILURE;
     }
     SubscribeEventInited = true;
     return FS_SUCCESS;
 }
 
 int32_t InitCommonEventMonitor(const std::string &pkgName, const DmPublishInfo &publishInfo,
     std::shared_ptr<FSNapiPublishCallback> callback)
 {
     g_subscriberPtr = SubscribeEvent::getInstance();
     if (g_subscriberPtr == nullptr) {
         LOGE("fileshare SubscribeEvent init fail");
         return FS_FAILURE;
     }
     if (g_subscriberPtr->SubscribeCommonEvent() == FS_SUCCESS) {
         LOGI("fileshare subscribe common event success");
     } else {
         delete g_subscriberPtr;
         return FS_FAILURE;
     }
     g_subscriberPtr->m_pkgName = pkgName;
     g_subscriberPtr->m_publishInfo = publishInfo;
     g_subscriberPtr->m_callback = callback;
     g_subscriberPtr->m_shareStatus = true;
     return FS_SUCCESS;
 }
 
 } // namespace FileShare
 } // namespace OHOS
 
 